(function () {
    if (window.JSBridge) {
        return;
    }
   let uniqueId = 1;
   const PROTOCOL = "nstc://";
   const SCHEMA_NATIVE_FETCH_CALL = PROTOCOL + "_native_fetch_call/";
   const SCHEMA_NATIVE_FETCH_CALL_RETURN = PROTOCOL + "_native_fetch_call_return/";
   const messageQueue4Native = [];
   const messageCallBacks4Native = {};
   const handlers4Native = {};

   function registerHandler(handlerName, func) {
       handlers4Native[handlerName] = func
   }

   function callNative(handlerName, data, callback) {
       const callbackId = uniqueId++;
       if (!data) {
           data = {}
       }
       const message = handlerName + "/" + callbackId + "/" + (typeof data === 'string' ? data : JSON.stringify(data));
       messageQueue4Native.push(message);
       if (callback) {
           messageCallBacks4Native[callbackId] = callback;
       }
       didPolicy(SCHEMA_NATIVE_FETCH_CALL);
   }

   function didPolicy(src) {
       let iframe = document.createElement('iframe');
       iframe.setAttribute("src", src);
       iframe.setAttribute("style", "display:none;");
       iframe.setAttribute("height", "0px");
       iframe.setAttribute("width", "0px");
       iframe.setAttribute("frameborder", "0");
       document.body.appendChild(iframe);
       iframe.parentNode.removeChild(iframe);
       iframe = null;
   }

   function _native_fetch_call() {
       let message = messageQueue4Native.pop();
       do {
           if (message) {
               didPolicy(SCHEMA_NATIVE_FETCH_CALL_RETURN + message);
           }
           message = messageQueue4Native.pop();
       } while (message)

   }

   function _native_call_return(callbackId, data) {
       const callback = messageCallBacks4Native[callbackId];
       if (callback) {
           callback(data);
           delete messageCallBacks4Native[callbackId];
       }
   }

   function _native_call_web(handlerName, data) {
       if (handlers4Native[handlerName]) {
           handlers4Native[handlerName](data);
       }
   }

   const JSBridge = window.JSBridge = {
       callNative,
       registerHandler,
       _native_fetch_call,
       _native_call_return,
       _native_call_web
   };

   const JSBridgeEvents = document.createEvent("Events");
   JSBridgeEvents.initEvent("JSBridgeReadyEvent");
   JSBridgeEvents.JSBridge = JSBridge;
   document.dispatchEvent(JSBridgeEvents);
})();